package vn.edu.ptithcm.pim.controller;

import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import vn.edu.ptithcm.pim.constant.Constants;
import vn.edu.ptithcm.pim.constant.UrlConstants;
import vn.edu.ptithcm.pim.dom.Project;
import vn.edu.ptithcm.pim.dom.Resource;
import vn.edu.ptithcm.pim.dom.Task;
import vn.edu.ptithcm.pim.service.EmployeeService;
import vn.edu.ptithcm.pim.service.ProjectService;
import vn.edu.ptithcm.pim.service.ResourceService;
import vn.edu.ptithcm.pim.service.TaskLogService;
import vn.edu.ptithcm.pim.service.TaskService;
import vn.edu.ptithcm.pim.service.UserService;
import vn.edu.ptithcm.pim.util.FileUtil;
import vn.edu.ptithcm.pim.util.ParamUtil;

@SuppressWarnings("deprecation")
public class ShowTaskDetailController extends SimpleFormController {
	private TaskService taskService;
	private UserService userService;
	private ProjectService projectService;
	private EmployeeService employeeService;
	private TaskLogService taskLogService;
	private ResourceService resourceService;

	public ShowTaskDetailController() {
		super();
		setSessionForm(true);
		setCommandName("task");
		setCommandClass(Task.class);
		setFormView(UrlConstants.TASK_DETAIL_URL);
	}

	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		Task task = null;
		String tcode = ParamUtil.getString(request, "tcode", "");
		task = taskService.findByCode(tcode);
		if (task == null) {
			task = new Task();
		}
		return task;
	}

	@Override
	public void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(
				dateFormat, true));
	}

	@Override
	protected ModelAndView showForm(HttpServletRequest request,
			HttpServletResponse response, BindException errors)
			throws Exception {
		Map<String, Object> bean = new HashMap<String, Object>();
		if (userService.isSignedIn(request)) {
			String loginName = userService.getCurrentLogin(request);
			bean.put("user", userService.findByLoginName(loginName));
			bean.put("isSigned", true);
			bean.put("isAdmin", userService.isAdmin(loginName));
			bean.put(Constants.LOGIN_NAME, loginName);
			bean.put(Constants.USER_NAME, userService.getUsername(loginName));
			String visa = userService.getVisa(loginName);
			bean.put("visa", visa);

			int pnum = ParamUtil.getInteger(request, "pnum", 0);

			Project project = projectService.findByNumber(pnum);
			bean.put("project", project);

			String tcode = ParamUtil.getString(request, "tcode", "");

			Task task = taskService.findByCode(tcode);

			String updatePageUrl = ParamUtil.getString(request,
					"updatePageUrl", "");
			String params = "?pnum=" + pnum + "&tcode=" + tcode;
			if (updatePageUrl.isEmpty()) {
				updatePageUrl = request
						.getRequestURL()
						.toString()
						.replaceAll(request.getServletPath(), "/updateTask.htm")
						+ params;
			}
			bean.put("updatePageUrl", updatePageUrl);
			bean.put("logs", taskLogService.getLogs(task.getTaskid()));
			String returnToFullPageURL = ParamUtil.getString(request,
					Constants.RETURN_TO_FULL_PAGE_URL, "");
			if (returnToFullPageURL.isEmpty()) {
				returnToFullPageURL = request.getHeader("referer");
			}
			bean.put(Constants.RETURN_TO_FULL_PAGE_URL, returnToFullPageURL);

			if (task.isAttachedfiles()) {
				List<Resource> resources = resourceService.findByTask(task
						.getTaskid());
				if (resources.size() > 0) {
					bean.put("isAttached", true);
					bean.put("author", resources.get(0).getAuthor());
					bean.put("createdAt", resources.get(0).getCreatedAt());
					bean.put("resources", resources);
				} else {
					bean.put("isAttached", false);
				}
			}

			if (task.getTasksForTaskid() != null
					&& task.getTasksForTaskid().size() > 0) {
				bean.put("hasParent", true);
			} else {
				bean.put("hasParent", false);
			}

			String fileName = task.getProject().getName() + "-"
					+ task.getCode() + ".pdf";
			params += "&fileName=" + fileName;
			String pdfFilePath = request.getRequestURL().toString() + params;
			bean.put("pdfFilePath", pdfFilePath);

			request.setAttribute("bean", bean);

			if (ParamUtil.isPdfRequest(request)) {
				response.setHeader("Content-disposition",
						"attachment; filename=" + fileName);
				response.setContentType("application/pdf");
				String pathToFile = FileUtil.generateTaskReport(request,
						response, task, Constants.UPLOADED_FILE_FOLDER);
				InputStream is = new FileInputStream(pathToFile);
				IOUtils.copy(is, response.getOutputStream());
				response.flushBuffer();
				response.getOutputStream().close();
			}
		} else {
			int pnum = ParamUtil.getInteger(request, "pnum", 0);
			String tcode = ParamUtil.getString(request, "tcode", "");

			String redirectLink = UrlConstants.TASK_DETAIL_URL
					+ UrlConstants.HTM + "?pnum=" + pnum + "&tcode=" + tcode;
			request.getSession().setAttribute("redirectLink", redirectLink);

			response.sendRedirect(UrlConstants.HOME_PAGE_URL + UrlConstants.HTM);
		}
		return super.showForm(request, response, errors);
	}

	public ProjectService getProjectService() {
		return projectService;
	}

	public void setProjectService(ProjectService projectService) {
		this.projectService = projectService;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public TaskLogService getTaskLogService() {
		return taskLogService;
	}

	public void setTaskLogService(TaskLogService taskLogService) {
		this.taskLogService = taskLogService;
	}

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}

	public ResourceService getResourceService() {
		return resourceService;
	}

	public void setResourceService(ResourceService resourceService) {
		this.resourceService = resourceService;
	}
}
